// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.

#include "stdafx.h"
#include "MFCOpenGLView.h"
#include "UberViewer.h"
#include "FreeImage.h"
#include "MainFrm.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define SQR(x) (x)*(x)

/////////////////////////////////////////////////////////////////////////////
// CMDITabsDemoView

IMPLEMENT_DYNCREATE(COpenGLView, CView)

BEGIN_MESSAGE_MAP(COpenGLView, CView)
	ON_WM_CREATE()
	ON_WM_SIZE()
	ON_WM_ERASEBKGND()
	ON_WM_KILLFOCUS()
	
    ON_WM_MOUSEMOVE()
    ON_WM_LBUTTONDOWN()
    ON_WM_RBUTTONDOWN()
    ON_WM_MBUTTONDOWN()
    ON_WM_MOUSEWHEEL()
    ON_WM_LBUTTONDBLCLK()

	ON_WM_CONTEXTMENU()
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMDITabsDemoView construction/destruction

COpenGLView::COpenGLView()
{
    TRACE("COpenGLView::COpenGLView");
    // Just clear the data.

  
//    m_Camera.x = 0;
//    m_Camera.y = -120;
//    m_Camera.z = 50;

//    m_Object.x = 0;
//    m_Object.y = 0;
//    m_Object.z = 0;
	m_xrot = 35.0;
	m_zrot = 0.0;

	m_xpan = 0.0;
	m_zoom = 500.0;
	m_zpan = -10.0;

//	CString str = "COpenGLView::COpenGLView m_pDocument = "; str.AppendFormat("%d", (int) m_pDocument);
//	AfxMessageBox(str);
}

COpenGLView::~COpenGLView()
{
    TRACE("COpenGLView(%s)::~COpenGLView", ((CString)(GetDocument()->GetTitle())).GetBuffer());
  // Shut down operations.
	delete m_pDC;
}

BOOL COpenGLView::PreCreateWindow(CREATESTRUCT& cs)
{
    TRACE("COpenGLView::PreCreateWindow");
//	CString str = "COpenGLView::PreCreateWindow m_pDocument = "; str.AppendFormat("%d", (int) m_pDocument);
//	AfxMessageBox(str);

	// TODO: Modify the Window class or styles here by modifying
    //  the CREATESTRUCT cs

    // An OpenGL window must be created with the following
    // flags and must not include CS_PARENTDC for the
    // class style.

    cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;

    return CView::PreCreateWindow(cs);
}

int COpenGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
    TRACE("COpenGLView::OnCreate");
//	CString str = "COpenGLView::OnCreate m_pDocument = "; str.AppendFormat("%d", (int) m_pDocument);
//	AfxMessageBox(str);

     if (CView::OnCreate(lpCreateStruct) == -1)
          return -1;

     // TODO: Add your specialized creation code here
    m_pDC = new CClientDC(this);

	if (m_pDC == NULL) // failure to get DC
	{
		AfxMessageBox("Couldn't get a valid DC.");
        return FALSE;
    }

	m_hDC = m_pDC->GetSafeHdc();

    // default pixel format for a single-buffered,
    // OpenGL-supporting, hardware-accelerated, 
    // RGBA-mode format. Pass in a pointer to a different
    // pixel format if you want something else
    PIXELFORMATDESCRIPTOR pfd = {
        sizeof(PIXELFORMATDESCRIPTOR),// size of this pfd
        1,                      // version number
        PFD_DRAW_TO_WINDOW |    // support window
          PFD_SUPPORT_OPENGL,   // support OpenGL
        PFD_TYPE_RGBA,          // RGBA type
        24,                     // 24-bit color depth
        0, 0, 0, 0, 0, 0,       // color bits ignored
        0,                      // no alpha buffer
        0,                      // shift bit ignored
        0,                      // no accumulation buffer
        0, 0, 0, 0,             // accum bits ignored
        16,                     // 16-bit z-buffer
        0,                      // no stencil buffer
        0,                      // no auxiliary buffer
        PFD_MAIN_PLANE,         // main layer
        0,                      // reserved
        0, 0, 0                 // layer masks ignored
    };

    int pixelformat;
 
    if (0 == (pixelformat = ChoosePixelFormat(m_hDC, &pfd)))
    {
		AfxMessageBox("ChoosePixelFormat failed.");
		return FALSE;
    }

    if (FALSE == SetPixelFormat(m_hDC, pixelformat, &pfd))
    {
        AfxMessageBox("SetPixelFormat failed.");
        return FALSE;
    }

    if (0 == (m_hRC = wglCreateContext(m_hDC)))
    {
		AfxMessageBox("wglCreateContext failed.");
        return FALSE;
    }

    if (FALSE == wglMakeCurrent(m_hDC, m_hRC))
    {
		AfxMessageBox("wglMakeCurrent failed.");
        return FALSE;
    }

    // specify black as clear color
    glClearColor( 0.76f, 0.76f, 0.76f, 0.0f );
    // specify the back of the buffer as clear depth
    glClearDepth( 1.0f );

	//allow transparency
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	// Depth buffering
	glEnable(GL_DEPTH_TEST);						// Enables Depth Testing
	glDepthFunc(GL_LEQUAL);							// The Type Of Depth Testing To Do

//	glEnable(GL_NORMALIZE);

	glEnable(GL_TEXTURE_2D);						// Enable Texture Mapping ( NEW )
	glShadeModel(GL_SMOOTH);						// Enable Smooth Shading
	glClearColor(0.76f, 0.76f, 0.76f, 1.0f);		// Black Background
	glClearDepth(1.0f);							// Depth Buffer Setup
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

	SetupMatrices();

	((CMainFrame*) GetParentFrame()->GetParentFrame())->UpdateDocPanes((CUberViewerDoc*)GetDocument());

    return 0;
}


void COpenGLView::OnKillFocus(CWnd *pNewWnd)
{
	TRACE("COpenGLView(%s)::OnKillFocus", ((CString)(GetDocument()->GetTitle())).GetBuffer());
//	CString str = "COpenGLView::OnKillFocus m_pDocument = "; str.AppendFormat("%d", (int) m_pDocument);
//	AfxMessageBox(str);

	if (pNewWnd)
	{
		CString str;
		pNewWnd->GetWindowTextA(str);
		if (str != "")
		{
			TRACE("COpenGLView(%s)::OnKillFocus gets focus", ((CString)(GetDocument()->GetTitle())).GetBuffer());
			((CMainFrame*) GetParentFrame()->GetParentFrame())->UpdateDocPanes((CUberViewerDoc*)GetDocument());
		}
		else
			TRACE("COpenGLView(%s)::OnKillFocus loses focus", ((CString)(GetDocument()->GetTitle())).GetBuffer());

	}
	CView::OnKillFocus(pNewWnd);
}


BOOL COpenGLView::OnEraseBkgnd(CDC* /*pDC*/) 
{
  return TRUE;
}

//bool sized = false;

void COpenGLView::OnSize(UINT nType, int cx, int cy) 
{
    TRACE("COpenGLView(%s)::OnSize x = %d y = %d", ((CString)(GetDocument()->GetTitle())).GetBuffer(), cx, cy);
//	CString str = "COpenGLView::OnSize m_pDocument = "; str.AppendFormat("%d", (int) m_pDocument);
//	AfxMessageBox(str);
//	sized = true;

    CView::OnSize(nType, cx, cy);
    
    if (cx <= 0 || cy <= 0)
        return;

    // save the width and height of the current window
    m_WindowWidth = cx;
    m_WindowHeight = cy;

    // compute the aspect ratio
    // this will keep all dimension scales equal
//	if (m_WindowWidth > m_WindowHeight)
	    m_AspectRatio = (GLdouble)m_WindowWidth/(GLdouble)m_WindowHeight;
//	else
//		m_AspectRatio = (GLdouble)m_WindowHeight/(GLdouble)m_WindowWidth;

    // Now, set up the viewing area-select the full client area
    glViewport(0, 0, m_WindowWidth, m_WindowHeight);


	GLenum err = glGetError();

    if ( GL_NO_ERROR != ::glGetError() )
    {
		AfxMessageBox("Error while trying to set viewport.");
    }

    // select the projection matrix as the recipient of
    // matrix operations (there's three to choose from)
    glMatrixMode(GL_PROJECTION);
    // initialize the projection matrix to a pristine state
    glLoadIdentity();

    // select the viewing volume. You do it after you
    // get the aspect ratio and set the viewport
    gluPerspective( 40.0f, m_AspectRatio, 1.0f, 10000.0f );

    // now select the modelview matrix and clear it
    // this is the mode we do most of our calculations in
    // so we leave it as the default mode.
    SetupMatrices();

}


void COpenGLView::OnDestroy() 
{
    TRACE("COpenGLView(%s)::OnDestroy", ((CString)(GetDocument()->GetTitle())).GetBuffer());

    CView::OnDestroy();
 
    // TODO: Add your message handler code here

    // this call makes the current RC not current
    if ( FALSE ==  ::wglMakeCurrent( 0, 0 ) )
    {
        AfxMessageBox("wglMakeCurrent failed.");
    }

    // delete the RC
    if ( m_hRC && (FALSE == ::wglDeleteContext( m_hRC )) )
    {
        AfxMessageBox("wglDeleteContext failed.");
    }
}



/////////////////////////////////////////////////////////////////////////////
// CMDITabsDemoView drawing
void SetColorMaterial(float r, float g, float b)
{
    float ambient[] = {r, g, b, 1.0};
    float specular[] = {0.2f, 0.2f, 0.2f, 1.0};
    float shininess = 0.3f;

	glColor3f(r, g, b);
    glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, ambient);
    glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
    glMaterialf (GL_FRONT, GL_SHININESS, shininess);
}


void COpenGLView::OnDraw(CDC* pDC) 
{
	static bool bBusy = false;

	if (bBusy) return;
	bBusy = true;

	wglMakeCurrent(m_hDC, m_hRC);

	SetupMatrices();
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	// Clear The Screen And The Depth Buffer

	// Draw basic axis
	glLineWidth(2.0);
	SetColorMaterial(1.0f, 0.0f, 0.0f);			// x->red
	glBegin(GL_LINES);
	glVertex3f( 0.0f, 0.0f, 0.0f);			// Top Of Triangle (Front)
	glVertex3f( 20.0f, 0.0f, 0.0f);			// Top Of Triangle (Front)
	glEnd();

	SetColorMaterial(0.0f, 1.0f, 0.0f);			// y->green
	glBegin(GL_LINES);
	glVertex3f( 0.0f, 0.0f, 0.0f);			// Top Of Triangle (Front)
	glVertex3f( 0.0f, 20.0f, 0.0f);			// Top Of Triangle (Front)
	glEnd();

	SetColorMaterial(0.0f, 0.0f, 1.0f);			// z->blue
	glBegin(GL_LINES);
	glVertex3f( 0.0f, 0.0f, 0.0f);			// Top Of Triangle (Front)
	glVertex3f( 0.0f, 0.0f, 20.0f);			// Top Of Triangle (Front)
	glEnd();

	RenderScene();

	glFinish();

	SwapBuffers(m_hDC);

/*	m_zrot += 0.13;
	if (m_zrot >= 360.0) m_zrot -= 360.0; 

	static double xstep = 0.07;
	m_xrot += xstep;
	if (m_xrot >= 90.0) xstep = -0.07; 
	else if (m_xrot <= 0.0) xstep = 0.07;

	SetupMatrices();
    Invalidate();  
*/
	bBusy = false;
}


void COpenGLView::OnLButtonDown(UINT nFlags, CPoint point)
{
	TRACE("COpenGLView(%s)::OnLButtonDown", ((CString)(GetDocument()->GetTitle())).GetBuffer());
//	GetSelectPoint(point);
    org.x = point.x;
    org.y = point.y;
}

void COpenGLView::OnMButtonDown(UINT nFlags, CPoint point)
{
	TRACE("COpenGLView(%s)::OnMButtonDown", ((CString)(GetDocument()->GetTitle())).GetBuffer());
    org.x = point.x;
    org.y = point.y;
}

void COpenGLView::OnRButtonDown(UINT nFlags, CPoint point)
{
	TRACE("COpenGLView(%s)::OnRButtonDown", ((CString)(GetDocument()->GetTitle())).GetBuffer());
    org.x = point.x;
    org.y = point.y;
}

void COpenGLView::OnMouseMove(UINT nFlags, CPoint point)
{
    bool update = false;

	if (m_hDC)
    {
        /* left button down so perform rotation */
        if (nFlags & MK_LBUTTON)
        {
            m_zrot += (float) 360.0 * (point.x - org.x) / m_WindowWidth;
			m_xrot += (float) 180.0 * (point.y - org.y) / m_WindowHeight;
			if (m_xrot > 90.0)       m_xrot =  90.0; 
			else if (m_xrot < -90.0) m_xrot = -90.0; 
            update = true;
        }

        /* center button down so perform zooming (panning in y-direction) */
        if (nFlags & MK_MBUTTON)
        {
            m_zoom += (float) (org.y - point.y);
            update = true;
        }

        /* right button down so perform panning (x- and z- direction) */
        if (nFlags & MK_RBUTTON)
        {
			m_xpan += (point.x - org.x) * 100.0 / m_WindowWidth;
            m_zpan += (org.y - point.y) * 100.0 / m_WindowHeight;
            update = true;
        }

        /* perform the rotation, translation and/or zoom */
        if (update)
        {
            org = point;
            SetupMatrices();
            Invalidate();
        }
    }
}

BOOL COpenGLView::OnMouseWheel(UINT nFlags, short zDelta ,CPoint pt)
{ 
    if (m_hDC)
    {
        m_zoom -= zDelta / 10.0;
        SetupMatrices();   
        Invalidate();    
    }
    return true;
}



int COpenGLView::SetupMatrices()
{
	TRACE("COpenGLView::SetupBasicMatrices");
/*	if (sized)
	{
		CString str = "COpenGLView::m_pDocument = "; str.AppendFormat("%d", (int) m_pDocument);
		AfxMessageBox(str);
		sized = false;
	}
*/
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    // select a default viewing transformation
    // of a 20 degree rotation about the X axis
    // then a -5 unit transformation along Z

	glRotatef(-90.0, 1.0, 0.0, 0.0); // correct the axis to match the world viewing
	glTranslatef(m_xpan, m_zoom, m_zpan);

	glRotatef(m_xrot, 1.0, 0.0, 0.0);
	glRotatef(m_zrot, 0.0, 0.0, 1.0);

	SetupLights();

	return true;
}

int	 COpenGLView::SetupLights()
{
	TRACE("COpenGLView::SetupLights");
//	CString str = "COpenGLView::m_pDocument = "; str.AppendFormat("%d", (int) m_pDocument);
//	AfxMessageBox(str);

	glEnable(GL_LIGHTING);
	glLightModelf(GL_AMBIENT, 0.2);
	glEnable(GL_LIGHT0);
	glEnable(GL_LIGHT1);

	// Create light components
	GLfloat ambientLight[] = { 0.0f, 0.0f, 0.0f, 1.0f };
	GLfloat diffuseLight[] = { 0.8f, 0.8f, 0.8, 1.0f };
	GLfloat position[] = { 1.0f, -1.0f, 1.0f, 0.0f };
	 
	// Assign created components to GL_LIGHT0
	glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
	glLightfv(GL_LIGHT0, GL_POSITION, position);

	// Create light components
	GLfloat ambientLight1[] = { 0.2f, 0.4f, 0.3f, 1.0f };
	GLfloat diffuseLight1[] = { 0.8f, 0.8f, 0.8, 1.0f };
	GLfloat position1[] = { -100.f, -100.0f, -40.0f, 1.0f };
	 
	// Assign created components to GL_LIGHT1
	glLightfv(GL_LIGHT1, GL_AMBIENT, ambientLight);
	glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuseLight);
	glLightfv(GL_LIGHT1, GL_POSITION, position);

    glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, 1.0f);
    glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.0f);
    glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.0f);
	return	0;
}



/*
void COpenGLView::InitializeCameraView()
{
	TRACE("COpenGLView::InitializeCameraView");

    /* convert camera and lookat coordinates to rotations, zoom and pannning values *
    if (m_Camera.x == 0 && m_Camera.y == 0 && m_Camera.z == 0)
        afx_msg("ERROR: Camera and target have the same position");

	float CamTargetXY = sqrt(SQR(m_Camera.x) + SQR(m_Camera.y)); 
    if (CamTargetXY == 0)
        m_zrot = 0;
    else
        m_zrot = -atan2(m_Camera.x, - m_Camera.y);
    m_xrot = atan2(m_Camera.z, CameraXY); 

    D3DXVECTOR3 dObjectCam = m_Object - m_Camera;
    float dTargetCamXYZ = sqrt(SQR(dCamTargetXY) + SQR(dCamTarget.z));
    m_zoom = - dObjectCam.x * dCamTarget.x - dObjectCam.y * dCamTarget.y - dObjectCam.z * dCamTarget.z; 
    m_zoom /= dTargetCamXYZ;

    D3DXVECTOR3 dProjectedObject = dCamTarget * (-m_zoom / dTargetCamXYZ);
    D3DXVECTOR3 dPanning = dObjectCam - dProjectedObject;
    m_xpan = dPanning.x;
    m_zpan = dPanning.z;
}
*/


/////////////////////////////////////////////////////////////////////////////
// CMDITabsDemoView printing

void COpenGLView::OnFilePrintPreview() 
{
	AFXPrintPreview (this);
}

BOOL COpenGLView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void COpenGLView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void COpenGLView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}


/////////////////////////////////////////////////////////////////////////////
// CMDITabsDemoView message handlers

void COpenGLView::OnContextMenu(CWnd*, CPoint point)
{
	theApp.ShowPopupMenu (IDR_CONTEXT_MENU, point, this);
}




/////////////////////////////////////////////////////////////////////////////
// CMDITabsDemoView diagnostics

#ifdef _DEBUG
void COpenGLView::AssertValid() const
{
	CView::AssertValid();
}

void COpenGLView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}
#endif //_DEBUG


unsigned int COpenGLView::AddTexture(int width, int height, int format, BYTE *data)
{
	unsigned int id;
	glGenTextures(1, &id);
	glBindTexture(GL_TEXTURE_2D, id);
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, format, GL_UNSIGNED_BYTE, data);
	return id;
}

void COpenGLView::ReplaceTexture(unsigned int id, int width, int height, int format, BYTE *data)
{
	glDeleteTextures(1, &id); 
	glBindTexture(GL_TEXTURE_2D, id);
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, format, GL_UNSIGNED_BYTE, data);
//	return id;
}

void COpenGLView::DeleteTexture(unsigned int id)
{
	glDeleteTextures(1, &id); 
}





/*
BOOL	CUberViewerView::CheckPickTriangleList(SIfcDocument *doc, int vertexIndex, int vertexCount, float *fDist)
{
	TRACE("CUberViewerView::CheckPickTriangleList");
    FLOAT fBary1, fBary2;
    bool    rValue = false;

//	vertexCount = vertexCount/3;
	int i = vertexIndex, i0, i1, i2;

	while  (i < vertexIndex + (3*vertexCount)) {
		i0 = doc->pIndices[i+0];
		i1 = doc->pIndices[i+1];
		i2 = doc->pIndices[i+2];
		if	(IntersectTriangle( m_PickRayOrig, m_PickRayDir, *((D3DXVECTOR3 *) &doc->pVertices[i0 * sizeof(CUSTOMVERTEX)/sizeof(float)]), *((D3DXVECTOR3 *) &doc->pVertices[i1 * sizeof(CUSTOMVERTEX)/sizeof(float)]), *((D3DXVECTOR3 *) &doc->pVertices[i2 * sizeof(CUSTOMVERTEX)/sizeof(float)]), fDist, &fBary1, &fBary2)) {
			rValue = true;
		}
		if	(IntersectTriangle( m_PickRayOrig, m_PickRayDir, *((D3DXVECTOR3 *) &doc->pVertices[i0 * sizeof(CUSTOMVERTEX)/sizeof(float)]), *((D3DXVECTOR3 *) &doc->pVertices[i2 * sizeof(CUSTOMVERTEX)/sizeof(float)]), *((D3DXVECTOR3 *) &doc->pVertices[i1 * sizeof(CUSTOMVERTEX)/sizeof(float)]), fDist, &fBary1, &fBary2)) {
			rValue = true;
		}

		i += 3;
	}

	return	rValue;
}
*
bool	CUberViewerView::CheckPick(CPoint &point)
{
	TRACE("COpenGLView::CheckPick");
/*	D3DXVECTOR3				vector;
    float					fDist = 100000000;
    D3DXMATRIX		matProj, matView, m;
	D3DXVECTOR3		v;

	SIfcDocument *selDoc = NULL;
	SIfc3DObject *selInst = NULL;

	SIfcDocument *doc = m_pModellingData->GetFirstDoc();
	while (doc)
	{
		if (doc->nrVertices > 0)
		{
			m_p3DDevice->GetTransform( D3DTS_PROJECTION, &matProj );

			// Compute the vector of the pick ray in screen space
			v.x =  ( ( ( 2.0f * point.x ) / m_iWidth  ) - 1 ) / matProj._11;
			v.y = -( ( ( 2.0f * point.y ) / m_iHeight ) - 1 ) / matProj._22;
			v.z =  1.0f;

			// Get the inverse view matrix
			m_p3DDevice->GetTransform( D3DTS_VIEW, &matView );

			D3DXMatrixMultiply( &matView, &doc->objectWorldTransform, &matView );
			D3DXMatrixInverse( &m, NULL, &matView );

			// Transform the screen space pick ray into 3D space
			m_PickRayDir.x  = v.x*m._11 + v.y*m._21 + v.z*m._31;
			m_PickRayDir.y  = v.x*m._12 + v.y*m._22 + v.z*m._32;
			m_PickRayDir.z  = v.x*m._13 + v.y*m._23 + v.z*m._33;
			m_PickRayOrig.x = m._41;
			m_PickRayOrig.y = m._42;
			m_PickRayOrig.z = m._43;

			// find the closest object of this document
			SIfc3DObject	* instance = doc->p3DObjects;
			while  (instance) 
			{
				if	(instance->parent && instance->checked && instance->parent->checked)
				{
					//if  (CheckPBoundingBox(instance)) {
						if  (CheckPickTriangleList(doc, instance->startIndex, instance->primitiveCount, &fDist))
						{
							selDoc = doc;
							selInst = instance;
						}
					//}
		//			if	(instance->boundingBox) {
		//				if	(CheckPickBoundingBox(instance, &fDist)) {
		//					selectedInstance = instance;
		//                } else {
		//                    ASSERT(1 == 0);
		//                }
		//			}
				}
				instance = instance->next;
			}
		}
        doc = doc->next;
    }
    m_pModellingData->SetSelection(selDoc, selInst);

    if	(selInst != NULL) {
	    return	true;
    } else {
	    return	false;
    }
*
	return false;
}
*/



/*
//-----------------------------------------------------------------------------
// Name: IntersectTriangle()
// Desc: Given a ray origin (orig) and direction (dir), and three vertices of
//       of a triangle, this function returns TRUE and the interpolated texture
//       coordinates if the ray intersects the triangle//-----------------------------------------------------------------------------
BOOL	CUberViewerView::IntersectTriangle(const D3DXVECTOR3& orig, const D3DXVECTOR3& dir, D3DXVECTOR3& v0, D3DXVECTOR3& v1, D3DXVECTOR3& v2, FLOAT* t, FLOAT* u, FLOAT* v)
{
	TRACE("CUberViewerView::IntersectTriangle");
    // Find vectors for two edges sharing vert0
    D3DXVECTOR3 edge1 = v1 - v0;
    D3DXVECTOR3 edge2 = v2 - v0;

    // Begin calculating determinant - also used to calculate U parameter
    D3DXVECTOR3 pvec;
    D3DXVec3Cross( &pvec, &dir, &edge2 );

    // If determinant is near zero, ray lies in plane of triangle
    float det = D3DXVec3Dot( &edge1, &pvec );

    D3DXVECTOR3 tvec;
    if( det > 0 )
    {
        tvec = orig - v0;
    }
    else
    {
        tvec = v0 - orig;
        det = -det;
    }

    if( det < 0.000001f )
        return FALSE;

    // Calculate U parameter and test bounds
    *u = D3DXVec3Dot( &tvec, &pvec );
    if( *u < 0.0f || *u > det )
        return FALSE;

    // Prepare to test V parameter
    D3DXVECTOR3 qvec;
    D3DXVec3Cross( &qvec, &tvec, &edge1 );

    // Calculate V parameter and test bounds
    *v = D3DXVec3Dot( &dir, &qvec );
    if( *v < 0.0f || *u + *v > det )
        return FALSE;

    // Calculate t, scale parameters, ray intersects triangle
    float dist = D3DXVec3Dot( &edge2, &qvec );
    FLOAT fInvDet = 1.0f / det;
    dist *= fInvDet;
    *u *= fInvDet;
    *v *= fInvDet;


	if	(dist < *t) {
		*t = dist;
		return	TRUE;
	}
	return	FALSE;
}
*/